<script setup lang="ts">
/**
 * @name DictionaryManagement
 * @description 字典配置
 */
import {
  Delete,
  Edit,
  Plus,
} from '@element-plus/icons-vue'
import type { Action } from 'element-plus'
import { ElTree } from 'element-plus'
import { FormModal, GroupFormModa } from './components'
import {
  defaultFormData,
  defaultGroupFormData,
} from './index'
import type {
  DictionaryEncoSaveOrUpdateParams,
  DictionaryGroupInfo,
  DictionaryGroupSaveOrUpdateParams,
  TableColumn,
} from '@/types'
import {
  sysDictionaryEncoApi,
  sysDictionaryGroupApi,
} from '@/api'

type AjaxDictionarySaveOrUpdateDictionaryGroupParams = any
// ------------------use------------------
// #region
const { form } = useKeepPageStore()
form(['/obsolete-device-catalog'])
const route = useRoute()
const { globalProperties, $confirm, $message }
  = useCurrentInstance()
const { withLoading, loading, vLoading }
  = useDefineLoading()
const [tableData, setTableData] = useState<any[]>([])
const [formData, setFormData] = useState<any>({
  ...defaultFormData,
})
const [dictionaryTree, setDictionaryTree] = useState<
  DictionaryGroupInfo[]
>([])
const [formModalTitle, setFormModalTitle]
  = useState<string>('')
const [groupFormModalTitle, setGroupFormModalTitle]
  = useState<string>('')

const [groupFormData, setGroupFormData] = useQuoteState<
  Partial<DictionaryGroupSaveOrUpdateParams>
>({
  ...defaultGroupFormData,
})
const [
  selectDictionaryGroupCode,
  setSelectDictionaryGroupCode,
] = useState('')

const columns: TableColumn<any>[] = [
  { key: uuid(), type: 'index', width: '80', label: 'ID' },
  {
    key: uuid(),
    label: '字典编码',
    prop: 'dicCode',
  },
  {
    key: uuid(),
    label: '字典KEY',
    prop: 'dicKey',
  },
  {
    key: uuid(),
    label: '字典VALUR',
    prop: 'dicValue',
  },
]
const defaultProps = {
  children: 'children',
  label: 'dicName',
}

const filterTextInput = ref<string>('')
const modalRef = ref<InstanceType<typeof FormModal>>()
const groupModalRef = ref<InstanceType<typeof FormModal>>()
const treeRef = ref<InstanceType<typeof ElTree>>()

const [isEditGroup, setIsEditGroup] = useState(false)

onMounted(async () => {
  await getDictionaryTree()
  if (
    selectDictionaryGroupCode.value
    || dictionaryTree.value.length === 0
  ) {
    return
  }

  setSelectDictionaryGroupCode(
    (route.query.dicCode! as string)
    ?? dictionaryTree.value[0]!.dicCode,
  )
  // await nextTick();
  getTableData()
})
// #endregion
// ------------------内置方法---------------------
// #region
watch(
  () => filterTextInput.value,
  (val: string) => {
    treeRef.value?.filter?.(val)
  },
)
// #endregion
// ------------------方法---------------------
// #region
async function getDictionaryTree() {
  const { data: res } = await withLoading(
    sysDictionaryGroupApi.queryTreeList,
    'tree',
  )()
  setDictionaryTree(res)
}
async function deleteData(id: number) {
  const res: Action = await $confirm(
    '该操作将永久删除该数据，确定删除？',
    '警告',
    {
      type: 'warning',
    },
  ).catch(e => e)

  if (res !== 'confirm')
    return
  const { code } = await sysDictionaryEncoApi.deleteById(
    id,
  )
  if (code !== 200)
    return
  getTableData()
}
async function deleteGroupData(id: number) {
  const res: Action = await $confirm(
    '该操作将永久删除该数据，确定删除？',
    '警告',
    {
      type: 'warning',
    },
  ).catch(e => e)

  if (res !== 'confirm')
    return
  const { code } = await sysDictionaryGroupApi.deleteById(
    id,
  )
  if (code !== 200)
    return
  getDictionaryTree()
}
async function showEditDialog(row: DictionaryEncoSaveOrUpdateParams) {
  modalRef.value?.open()
  await nextTick()
  setFormModalTitle('编辑')
  setFormData({ ...defaultFormData, ...row })
}
async function showAddDialog() {
  modalRef.value?.open()
  await nextTick()
  if (!selectDictionaryGroupCode.value) {
    globalProperties.$message.info(
      '请先选择左侧字典分类！',
    )
    return
  }
  setFormModalTitle('新增')
  setFormData({ ...defaultFormData, id: undefined })
}
async function getTableData() {
  const { data: res } = await withLoading(
    sysDictionaryEncoApi.queryList,
  )(selectDictionaryGroupCode.value)
  setTableData(res)
}
async function addOrUpdateData(row: Partial<DictionaryEncoSaveOrUpdateParams>) {
  const params = {
    ...row,
    dicCode: selectDictionaryGroupCode.value,
  }
  removeUnnecessaryParams(params)
  const { code } = await sysDictionaryEncoApi.saveOrUpdate(
    params,
  )
  if (code !== 200)
    return
  getTableData()
  modalRef.value?.close()
  $message.success('保存成功！')
}
function filterNode(value: string, data: any) {
  if (!value)
    return true
  return data.dicName.includes(value)
}
function handlerTreeNodeClick(node: DictionaryGroupInfo) {
  if (node.children)
    return
  setSelectDictionaryGroupCode(node.dicCode)
  getTableData()
}
async function showEditGroupDialog(row: AjaxDictionarySaveOrUpdateDictionaryGroupParams) {
  groupModalRef.value?.open()
  setIsEditGroup(true)
  await nextTick()
  setGroupFormModalTitle('编辑字典分组')
  setGroupFormData({ ...defaultGroupFormData, ...row })
}
async function showAddGroupDialoog() {
  groupModalRef.value?.open()
  setIsEditGroup(false)
  await nextTick()
  setGroupFormModalTitle('新增字典分组')
  setGroupFormData({
    ...defaultGroupFormData,
    id: undefined,
  })
}
async function addOrUpdateGroupData(row: Partial<DictionaryGroupSaveOrUpdateParams>) {
  const params = { ...row }
  removeUnnecessaryParams(params)
  if (!params.parentId) {
    params.parentId = 0
  }
  const { code } = await sysDictionaryGroupApi.saveOrUpdate(
    params,
  )
  if (code !== 200)
    return
  getDictionaryTree()
  groupModalRef.value?.close()
  $message.success('保存成功！')
}

onMounted(() => {
  const route = useRoute()
  if (route.query.dicCode) {
    setSelectDictionaryGroupCode(route.query.dicCode as string)
    getTableData()
  }
})
// #endregion
</script>

<template>
  <div
    class="padding-sm align-center dictionary flex gap-sm container"
  >
    <div
      v-loading="{
        space: 'tree',
      }"
      class="height-fill flex-incompressible padding-sm flex-direction dictionary-left box-border flex gap-xs"
    >
      <h5
        class="flex-incompressible margin-0 align-center flex justify-between"
      >
        <span>字典分组</span>
        <TdButton
          title="添加字典分组"
          :icon="Plus"
          :disabled="!$power('add')"
          type="primary"
          class="fs-18"
          @click="showAddGroupDialoog"
        />
      </h5>
      <el-input
        v-model="filterTextInput"
        placeholder="关键字"
        class="flex-incompressible"
      />
      <BScrollbar>
        <ElTree
          ref="treeRef"
          class="flex-fillRemaining"
          :data="dictionaryTree"
          :props="defaultProps"
          accordion
          highlight-current
          default-expand-all
          node-key="dicCode"
          :current-node-key="selectDictionaryGroupCode"
          :filter-node-method="filterNode"
          @contextmenu.prevent
          @node-click="handlerTreeNodeClick"
        >
          <template #default="{ node, data }">
            <div
              class="align-center width-fill tree-box flex justify-between"
            >
              <span>{{ node.label }}</span>
              <div class="tree-box__tools" @click.stop>
                <el-button
                  link
                  type="primary"
                  :icon="Edit"
                  :disabled="!$power('edit')"
                  class="margin-0"
                  style="margin: 0 5px"
                  @click="showEditGroupDialog(data)"
                />

                <el-button
                  link
                  type="danger"
                  :disabled="!$power('delete')"
                  :icon="Delete"
                  class="margin-0"
                  @click="deleteGroupData(data.id)"
                />
              </div>
            </div>
          </template>
        </ElTree>
      </BScrollbar>
    </div>
    <div
      class="height-fill flex-fillRemaining flex-direction overflow dictionary-right box-border flex"
    >
      <view-table
        :loading="loading"
        :columns="columns"
        :data="tableData"
      >
        <template #actions>
          <el-button
            plain
            type="success"
            :disabled="!$power('add')"
            :icon="Plus"
            @click="showAddDialog"
          >
            新增
          </el-button>
        </template>
        <template #operate="{ row }">
          <TdButton
            title="编辑"
            :icon="Edit"
            type="primary"
            @click="showEditDialog(row)"
          />
          <el-divider direction="vertical" />
          <TdButton
            title="删除"
            :icon="Delete"
            type="danger"
            @click="deleteData(row.id)"
          />
        </template>
      </view-table>
    </div>
    <FormModal
      ref="modalRef"
      v-model:data="formData"
      :code="selectDictionaryGroupCode"
      :title="formModalTitle"
      @save-success="addOrUpdateData(formData)"
    />
    <GroupFormModa
      ref="groupModalRef"
      :title="groupFormModalTitle"
      :data="groupFormData"
      :is-edit="isEditGroup"
      @save-success="addOrUpdateGroupData(groupFormData)"
    />
  </div>
</template>

<style lang="scss" scoped>
//------------------组件样式------------------
.dictionary {
  --dictionary-lw: 300px;
  &-left {
    background-color: var(--el-bg-color);
    border: 1px solid var(--el-border-color-light);
    border-radius: 4px;
    width: var(--dictionary-lw);

    transition: all var(--motion-bezier) 0.3s;
    &:hover {
      box-shadow: 0 8px 32px #0000000d;
    }

    h5 {
      color: var(--el-text-color-primary);
    }
  }
  &-right {
    &__header {
      border-left: 4px solid var(--el-color-primary);
    }
  }
}
.tree-box {
  &__tools {
    opacity: 0;
    transition: opacity 0.2s;
  }
}
.el-tree {
  :deep(.el-tree-node__content:hover) {
    .tree-box__tools {
      opacity: 1;
    }
  }
}
//-------------样式穿透-------------
</style>
